﻿using System;
using System.Collections.Generic;
 
using System.Text;
using System.Runtime.InteropServices;


namespace HDF5
{
    using hid_t = System.Int32;
    using herr_t = System.Int32;
    using hsize_t = System.UInt64;
    using hssize_t = System.Int64;
    using hunsigned = System.UInt32;

    using hbool_t = System.UInt32;
    using htri_t = System.Int32;
    using ssize_t = System.Int64;

    using haddr_t = System.UInt64;

    using uint32_t = System.UInt32;
    using uint64_t = System.UInt64;

    using H5O_msg_crt_idx_t = System.UInt32;

    using size_t = System.UInt32;

    using off_t = System.Int32;

    using H5E_major_t = System.Int32;
    using H5E_minor_t = System.Int32;

    using time_t = System.Int64;
    using H5Z_filter_t = System.Int32;

    #region enums
    /* Special parameters for ScaleOffset filter*/
    public enum H5Z_SO_scale_type_t {
        H5Z_SO_FLOAT_DSCALE = 0,
        H5Z_SO_FLOAT_ESCALE = 1,
        H5Z_SO_INT          = 2
    }  

 
 

    /* Values to decide if EDC is enabled for reading data */
    public enum H5Z_EDC_t {
        H5Z_ERROR_EDC       = -1,   /* error value */
        H5Z_DISABLE_EDC     = 0,
        H5Z_ENABLE_EDC      = 1,
        H5Z_NO_EDC          = 2     /* must be the last */
    } 

    /* Return values for filter callback function */
    public enum H5Z_cb_return_t {
        H5Z_CB_ERROR  = -1,
        H5Z_CB_FAIL   = 0,    /* I/O should fail if filter fails. */
        H5Z_CB_CONT   = 1,    /* I/O continues if filter fails.   */
        H5Z_CB_NO     = 2
    }
    #endregion enums

    #region delegates
    /*
     * Before a dataset gets created, the "can_apply" callbacks for any filters used
     * in the dataset creation property list are called
     * with the dataset's dataset creation property list, the dataset's datatype and
     * a dataspace describing a chunk (for chunked dataset storage).
     *
     * The "can_apply" callback must determine if the combination of the dataset
     * creation property list setting, the datatype and the dataspace represent a
     * valid combination to apply this filter to.  For example, some cases of
     * invalid combinations may involve the filter not operating correctly on
     * certain datatypes (or certain datatype sizes), or certain sizes of the chunk
     * dataspace.
     *
     * The "can_apply" callback can be the NULL pointer, in which case, the library
     * will assume that it can apply to any combination of dataset creation
     * property list values, datatypes and dataspaces.
     *
     * The "can_apply" callback returns positive a valid combination, zero for an
     * invalid combination and negative for an error.
     */
    public delegate herr_t H5Z_can_apply_func_t(hid_t dcpl_id, hid_t type_id, hid_t space_id);

    /*
     * After the "can_apply" callbacks are checked for new datasets, the "set_local"
     * callbacks for any filters used in the dataset creation property list are
     * called.  These callbacks receive the dataset's private copy of the dataset
     * creation property list passed in to H5Dcreate (i.e. not the actual property
     * list passed in to H5Dcreate) and the datatype ID passed in to H5Dcreate
     * (which is not copied and should not be modified) and a dataspace describing
     * the chunk (for chunked dataset storage) (which should also not be modified).
     *
     * The "set_local" callback must set any parameters that are specific to this
     * dataset, based on the combination of the dataset creation property list
     * values, the datatype and the dataspace.  For example, some filters perform
     * different actions based on different datatypes (or datatype sizes) or
     * different number of dimensions or dataspace sizes.
     *
     * The "set_local" callback can be the NULL pointer, in which case, the library
     * will assume that there are no dataset-specific settings for this filter.
     *
     * The "set_local" callback must return non-negative on success and negative
     * for an error.
     */
    public delegate herr_t H5Z_set_local_func_t(hid_t dcpl_id, hid_t type_id, hid_t space_id);

    /*
     * A filter gets definition flags and invocation flags (defined above), the
     * client data array and size defined when the filter was added to the
     * pipeline, the size in bytes of the data on which to operate, and pointers
     * to a buffer and its allocated size.
     *
     * The filter should store the result in the supplied buffer if possible,
     * otherwise it can allocate a new buffer, freeing the original.  The
     * allocated size of the new buffer should be returned through the BUF_SIZE
     * pointer and the new buffer through the BUF pointer.
     *
     * The return value from the filter is the number of bytes in the output
     * buffer. If an error occurs then the function should return zero and leave
     * all pointer arguments unchanged.
     */
    public delegate size_t H5Z_func_t(hunsigned flags, size_t cd_nelmts,
			         hunsigned[] cd_values, size_t nbytes,
			         ref size_t buf_size, IntPtr[] buf);

    #endregion delegates
    public static class H5Z
    {
        #region constants
        /* Filter IDs */
        public static hid_t H5Z_FILTER_ERROR =	-1;//	/*no filter			*/
        public static hid_t H5Z_FILTER_NONE	=	0;//	/*reserved indefinitely		*/
        public static hid_t H5Z_FILTER_DEFLATE	= 1 ;//	/*deflation like gzip	     	*/
        public static hid_t H5Z_FILTER_SHUFFLE  =    2;       /*shuffle the data              */
        public static hid_t H5Z_FILTER_FLETCHER32 =  3 ;      /*fletcher32 checksum of EDC    */
        public static hid_t H5Z_FILTER_SZIP    =     4   ;    /*szip compression              */
        public static hid_t H5Z_FILTER_NBIT   =      5   ;    /*nbit compression              */
        public static hid_t H5Z_FILTER_SCALEOFFSET = 6    ;   /*scale+offset compression      */
        public static hid_t H5Z_FILTER_RESERVED =    256;	/*filter ids below this value are reserved for library use */
        public static hid_t H5Z_FILTER_MAX	=	65535;	/*maximum filter id		*/

        public static hid_t H5Z_FILTER_ALL	= 	0	;/* Symbol to remove all filters in H5Premove_filter */
        public static hid_t H5Z_MAX_NFILTERS = 32;     /* Maximum number of filters allowed in a pipeline */
                                        /* (should probably be allowed to be an
                                         * unlimited amount, but currently each
                                         * filter uses a bit in a 32-bit field,
                                         * so the format would have to be
                                         * changed to accomodate that)*/

        /* Flags for filter definition (stored) */
        public static hid_t H5Z_FLAG_DEFMASK =	0x00ff;	/*definition flag mask		*/
        public static hid_t H5Z_FLAG_MANDATORY  =    0x0000;  /*filter is mandatory		*/
        public static hid_t H5Z_FLAG_OPTIONAL =	0x0001;	/*filter is optional		*/

        /* Additional flags for filter invocation (not stored) */
        public static hid_t H5Z_FLAG_INVMASK =	0xff00;	/*invocation flag mask		*/
        public static hid_t H5Z_FLAG_REVERSE =	0x0100;	/*reverse direction; read	*/
        public static hid_t H5Z_FLAG_SKIP_EDC = 0x0200;	/*skip EDC filters for read	*/

        /* Special parameters for szip compression */
        /* [These are aliases for the similar definitions in szlib.h, which we can't
         * include directly due to the duplication of various symbols with the zlib.h
         * header file] */
        public static hid_t H5_SZIP_ALLOW_K13_OPTION_MASK  = 1;
        public static hid_t H5_SZIP_CHIP_OPTION_MASK    =    2;
        public static hid_t H5_SZIP_EC_OPTION_MASK      =    4;
        public static hid_t H5_SZIP_NN_OPTION_MASK      =    32;
        public static hid_t H5_SZIP_MAX_PIXELS_PER_BLOCK =   32;

        /* Macros for the shuffle filter */
        public static hid_t H5Z_SHUFFLE_USER_NPARMS  =  0;    /* Number of parameters that users can set */
        public static hid_t H5Z_SHUFFLE_TOTAL_NPARMS =  1 ;   /* Total number of parameters for filter */

        /* Macros for the szip filter */
        public static hid_t H5Z_SZIP_USER_NPARMS  =  2;       /* Number of parameters that users can set */
        public static hid_t H5Z_SZIP_TOTAL_NPARMS  = 4;       /* Total number of parameters for filter */
        public static hid_t H5Z_SZIP_PARM_MASK  =    0;       /* "User" parameter for option mask */
        public static hid_t H5Z_SZIP_PARM_PPB   =    1;       /* "User" parameter for pixels-per-block */
        public static hid_t H5Z_SZIP_PARM_BPP  =     2;       /* "Local" parameter for bits-per-pixel */
        public static hid_t H5Z_SZIP_PARM_PPS    =   3;       /* "Local" parameter for pixels-per-scanline */

        /* Macros for the nbit filter */
        public static hid_t H5Z_NBIT_USER_NPARMS  =   0;     /* Number of parameters that users can set */

        /* Macros for the scale offset filter */
        public static hid_t H5Z_SCALEOFFSET_USER_NPARMS =     2;    /* Number of parameters that users can set */


        /* Special parameters for ScaleOffset filter*/
        public static hid_t H5Z_SO_INT_MINBITS_DEFAULT = 0;

        /* Current version of the H5Z_class_t struct */
        public static hid_t H5Z_CLASS_T_VERS = 1;

        /* Bit flags for H5Zget_filter_info */
        public static hid_t H5Z_FILTER_CONFIG_ENCODE_ENABLED = 0x0001;
        public static hid_t H5Z_FILTER_CONFIG_DECODE_ENABLED = 0x0002;

        #endregion constants

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Zfilter_avail(H5Z_filter_t filter) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Zget_filter_info( H5Z_filter_t filter, out hunsigned filter_config ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Zregister(const H5Z_class_t *filter_class) ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Zunregister(H5Z_filter_t filter) ;
    }
}
